<template>
  <PageWrapper>
    <n-grid cols="1 s:1 m:1 l:4 xl:4 2xl:4" responsive="screen" :x-gap="12">
      <n-gi span="1">
        <n-card :segmented="{ content: 'soft' }" :bordered="false" size="small">
          <template #header>
            <n-space>
              <n-button type="info" icon-placement="left" @click="openCreateDrawer">
                添加菜单
                <template #icon>
                  <div class="flex items-center">
                    <n-icon size="14">
                      <FileAddOutlined />
                    </n-icon>
                  </div>
                </template>
              </n-button>

              <n-button type="info" ghost icon-placement="left" @click="packHandle">
                全部{{ expandedKeys.length ? '收起' : '展开' }}
                <template #icon>
                  <div class="flex items-center">
                    <n-icon size="14">
                      <AlignLeftOutlined />
                    </n-icon>
                  </div>
                </template>
              </n-button>
            </n-space>
          </template>
          <div class="w-full menu">
            <n-input type="input" v-model:value="pattern" placeholder="输入菜单名称搜索">
              <template #suffix>
                <n-icon size="18" class="cursor-pointer">
                  <SearchOutlined />
                </n-icon>
              </template>
            </n-input>
            <div class="py-3 menu-list">
              <template v-if="loading">
                <div class="flex items-center justify-center py-4">
                  <n-spin size="medium" />
                </div>
              </template>
              <template v-else>
                <n-tree
                  block-line
                  cascade
                  :virtual-scroll="true"
                  :pattern="pattern"
                  :data="treeData"
                  key-field="id"
                  label-field="menu_name"
                  :expandedKeys="expandedKeys"
                  style="max-height: 650px; overflow: hidden"
                  @update:selected-keys="selectedTree"
                  @update:expanded-keys="onExpandedKeys"
                />
              </template>
            </div>
          </div>
        </n-card>
      </n-gi>
      <n-gi span="3">
        <n-card :segmented="{ content: 'soft' }" :bordered="false" size="small">
          <template #header>
            <n-space>
              <span>编辑{{ getTypeMsg }}{{ treeItemTitle ? `：${treeItemTitle}` : '' }}</span>
              <n-divider vertical />
              <n-text depth="3" class="text-sm"> 从左侧列表选择一项后，进行编辑 </n-text>
            </n-space>
          </template>
          <template #header-extra>
            <n-popconfirm @positive-click="handleDeleteMenu" v-if="isEditMenu">
              <template #trigger>
                <n-button quaternary type="info">删除{{ getTypeMsg }}</n-button>
              </template>
              确定要删除 {{ treeItemTitle }} {{ getTypeMsg }}吗？
            </n-popconfirm>
          </template>
          <!-- 表单 -->
          <n-spin :show="loadingR">
            <MenuForm
              ref="menuFormRef"
              :permissionList="treeData"
              @change="menuChange"
              class="w-2/4 ml-10"
              isShowSubmit
            />
          </n-spin>
        </n-card>
      </n-gi>
    </n-grid>
    <CreateDrawer
      ref="createDrawerRef"
      :title="drawerTitle"
      :permissionList="treeData"
      @change="menuChange"
    />
  </PageWrapper>
</template>
<script lang="ts" setup>
  import { ref, unref, onMounted, computed } from 'vue';
  import { useMessage } from 'naive-ui';
  import { AlignLeftOutlined, SearchOutlined, FileAddOutlined } from '@vicons/antd';
  import { menuList, menuInfo, deleteMenu } from '@/api/system/menu';
  import { getTreeItem } from '@/utils';
  import CreateDrawer from './CreateDrawer.vue';
  import MenuForm from './MenuForm.vue';

  const createDrawerRef = ref();
  const message = useMessage();

  let treeItemKey = ref([]);

  let expandedKeys = ref([]);

  const treeData = ref([]);

  const loading = ref(true);
  const loadingR = ref(false);

  const isEditMenu = ref(false);
  const treeItemTitle = ref('');
  const pattern = ref('');
  const drawerTitle = ref('');
  const menuFormRef = ref();

  const menuTypeMsg = ref(['目录', '菜单', '按钮']);

  const formParams = ref({
    id: null,
    parent_id: 0,
    active_menu: '',
    affix: false,
    always_show: true,
    icon: '',
    is_cache: 1,
    is_frame: 1,
    is_visible: 0,
    menu_name: '',
    menu_type: 0,
    open_type: 1,
    status: 0,
    order_num: null,
    permission_code: '',
    permission_name: '',
    query: '',
    route_url: '',
    route_name: '',
    component: '',
    redirect: '',
  });

  const getTypeMsg = computed(() => {
    return menuTypeMsg.value[formParams.value.menu_type];
  });

  function handleDeleteMenu() {
    deleteMenu({ id: formParams.value.id }).then(() => {
      message.success('删除成功');
      isEditMenu.value = false;
      treeItemTitle.value = '';
      menuFormRef.value.handleReset();
      getPermissionList();
    });
  }

  function openCreateDrawer() {
    drawerTitle.value = '添加菜单';
    const { openDrawer } = createDrawerRef.value;
    openDrawer();
  }

  async function selectedTree(keys) {
    if (keys.length) {
      const treeItem = getTreeItem(unref(treeData), keys[0], 'id');
      treeItemKey.value = keys;
      treeItemTitle.value = treeItem.menu_name;
      loadingR.value = true;
      const info = await menuInfo({ id: keys[0] });
      const newMenuInfo = {
        id: info.id,
        parent_id: info.parent_id,
        active_menu: info.active_menu,
        affix: info.affix,
        always_show: info.always_show,
        component: info.component,
        icon: info.icon,
        is_cache: info.is_cache,
        is_frame: info.is_frame,
        is_visible: parseInt(info.is_visible),
        menu_name: info.menu_name,
        menu_type: info.menu_type,
        open_type: info.open_type,
        status: parseInt(info.status),
        order_num: info.order_num,
        permission_code: info.permission_code,
        permission_name: info.permission_name,
        query: info.query,
        route_url: info.route_url,
        route_name: info.route_name,
        redirect: info.redirect,
        frame_src: info.frame_src,
        is_root: info.is_root,
      };
      formParams.value = newMenuInfo;
      menuFormRef.value.setData(newMenuInfo);
      isEditMenu.value = true;
      loadingR.value = false;
    } else {
      isEditMenu.value = false;
      treeItemKey.value = [];
      treeItemTitle.value = '';
    }
  }

  function packHandle() {
    if (expandedKeys.value.length) {
      expandedKeys.value = [];
    } else {
      expandedKeys.value = unref(treeData).map((item: any) => item.id) as [];
    }
  }

  async function getPermissionList() {
    loading.value = true;
    const list = await menuList();
    treeData.value = list;
    loading.value = false;
  }

  async function menuChange() {
    getPermissionList();
    treeItemTitle.value = '';
    isEditMenu.value = false;
  }

  onMounted(async () => {
    getPermissionList();
  });

  function onExpandedKeys(keys) {
    expandedKeys.value = keys;
  }
</script>

<style lang="less" scoped></style>
